/*
 * Copyright (C) 2019 ~ 2022 Uniontech Software Technology Co.,Ltd.
 *
 * Author:     yanghongwei <yanghongwei@uniontech.com>
 *
 * Maintainer: yanghongwei <yanghongwei@uniontech.com>
 */

#pragma once // 防止使用COMMON_H跟其他.h冲突

#include <string>

/**
 * @brief 事件通知类型
 */
enum NotifyType {
    Unknown = 0,
    I_Notify, // inotify
    Fa_Notify, // fanotify
};

// FileEvent 文件操作具体事件类型（inotify和fanotify整合，在各自内部会转换为具体的系统事件）
#define ACCESS 0x000001
#define ATTRIB 0x000002
#define CLOSE_WRITE 0x000004
#define CLOSE_NOWRITE 0x000008
#define CLOSE (CLOSE_WRITE | CLOSE_NOWRITE)
#define CREATE 0x000010
#define DELETE 0x000020
#define DELETE_SELF 0x000040
#define MODIFY 0x000080
#define MOVE_SELF 0x000100
#define MOVED_FROM 0x000200
#define MOVED_TO 0x000400
#define OPEN 0x000800
#define OPEN_EXEC 0x001000
#define ACCESS_PERM 0x002000
#define OPEN_PERM 0x004000
#define OPEN_EXEC_PERM 0x008000
#define ONDIR 0x010000

/**
 * @brief 通知节点
 * 这个数据结构用来加入到事件监听队列
 * TODO: 还需要优化
 */
struct NotifyNode {
    std::string file; // 可以是目录
    uint32_t events; // 要监听的事件类型(由上面的类型组成eg:ACCESS|CREATE)
    void *object {nullptr}; // 标记是哪个注册对象，可以不用初始化

    bool operator==(const NotifyNode &other) const
    {
        if (this == &other) {
            return true;
        }

        return this->file == other.file && this->events == other.events && this->object == other.object;
    }

    // map排序使用，没有具体作用，所以直接file字符串比较
    bool operator<(const NotifyNode &other) const
    {
        if (this == &other) {
            return true;
        }

        return this->file < other.file;
    }
};
